package com.els.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.aggregations.metrics.max.InternalMax;
import org.elasticsearch.search.aggregations.metrics.min.InternalMin;
import org.elasticsearch.search.aggregations.metrics.sum.InternalSum;
import org.elasticsearch.search.aggregations.metrics.sum.Sum;
import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCount;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;

public class QueryRespVO {
	private static final boolean Infinity = false;
	private List<JsonObject> data;
	private long total;
	private Aggregations aggs;
//	private List<Dimension> dimensions;
	
	private JsonArray chartData;
	private JsonArray category;
	private JsonObject response;
	
	
	public JsonObject getResponse() {
		return response;
	}

	public void setResponse(JsonObject response) {
		this.response = response;
	}

	public JsonArray getCategory() {
		return category;
	}

	public void setCategory(JsonArray category) {
		this.category = category;
	}

	public JsonArray getChartData() {
		return chartData;
	}

	public void setChartData(JsonArray chartData) {
		this.chartData = chartData;
	}

	public List<JsonObject> getData() {
		return data;
	}

	public void setData(List<JsonObject> data) {
		this.data = data;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public void setAggs(Aggregations aggs) {
		this.aggs = aggs;
	}

	public Aggregations aggs() {
		return this.aggs;
	}

	public List<JsonObject> getAgg(String term) {
		Terms agg = aggs.get(term);
		if (agg == null)
			return null;
		List<JsonObject> resultList = new ArrayList<JsonObject>();
		List<Bucket> buckets = agg.getBuckets();
		for (Bucket bucket : buckets) {
			//els 1.4.4bug，空值JAVA API会失败，所以屏蔽空值
			if("".equals(bucket.getKey()))continue;
			JsonObject element = new JsonObject();
			element.addProperty("Name", bucket.getKeyAsString());
			element.addProperty("Count", bucket.getDocCount());
			resultList.add(element);
		}
		return resultList;
	}
	public List<JsonObject> getAggSubTermAgg(String term,String subTerm) {
		//TODO
		Terms agg = aggs.get(term);
		if (agg == null)
			return null;
		List<JsonObject> resultList = new ArrayList<JsonObject>();
		List<Bucket> buckets = agg.getBuckets();
		for (Bucket bucket : buckets) {
			if("".equals(bucket.getKey()))continue;
			JsonObject element = new JsonObject();
			element.addProperty("Name", bucket.getKeyAsString());
			element.addProperty("Count", bucket.getDocCount());
			
			Terms subAgg = bucket.getAggregations().get(subTerm);
			List<JsonObject> subList = new ArrayList<JsonObject>();
			List<Bucket> subBuckets = subAgg.getBuckets();
			for (Bucket bucket2 : subBuckets) {
				if ("".equals(bucket2.getKey()))continue;
				JsonObject jsonObject = new JsonObject();
				jsonObject.addProperty("Name", bucket2.getKeyAsString());
				jsonObject.addProperty("Count", bucket2.getDocCount());
				subList.add(jsonObject);
			}
//			element.addProperty(subTerm, subList);
			element.add("subData", new Gson().toJsonTree(subList));
			resultList.add(element);
		}
		return resultList;

	}
	
	
	
	
	
	/**
	 * 取sum聚合的值
	 * @param term
	 * @return
	 */
	public double getSumAgg(String term) {
		InternalSum agg = aggs.get(term);
		if (agg==null) {
			return 0;
		}
		return getDouble(agg.getValue());
	}
	/**
	 * 父聚合term，子聚合sum
	 * @param term 父聚合名
	 * @param subTerm 子聚合名
	 * @return
	 */
	public List<JsonObject> getTermSubSumAgg(String term,String subTerm) {
		Terms agg = aggs.get(term);
		if (agg==null) {
			return null;
		}
		List<JsonObject> jsonObjects = new ArrayList<JsonObject>();
		List<Bucket> buckets = agg.getBuckets();
		for (Bucket bucket : buckets) {
			JsonObject jsonObject = new JsonObject();
			jsonObject.addProperty("Name", bucket.getKeyAsString());
			jsonObject.addProperty("Count", bucket.getDocCount());
			InternalSum subAgg = bucket.getAggregations().get(subTerm);
			jsonObject.addProperty(subTerm, getDouble(subAgg.getValue()));
			jsonObjects.add(jsonObject);
		}
		return jsonObjects;
	}
	/**
	 * 取avg聚合的值
	 * @param term
	 * @return
	 */
	public double getAvgAgg(String term) {
		InternalAvg agg = aggs.get(term);
		if (agg==null) {
			return 0;
		}
		return getDouble(agg.getValue());
	}
	/**
	 * 父聚合term，子聚合avg 
	 * @param term
	 * @param subTerm
	 * @return
	 */
	public List<JsonObject> getTermSubAvgAgg(String term,String subTerm) {
		Terms agg = aggs.get(term);
		if (agg==null) {
			return null;
		}
		List<JsonObject> list = new ArrayList<JsonObject>();
		List<Bucket> buckets = agg.getBuckets();
		for (Bucket bucket : buckets) {
			JsonObject object = new JsonObject();
			object.addProperty("Name", bucket.getKeyAsString());
			object.addProperty("Count", bucket.getDocCount());
			InternalAvg subAgg = bucket.getAggregations().get(subTerm);
			object.addProperty(subTerm, getDouble(subAgg.getValue()));
			list.add(object);
		}
		return list;
	}
	/**
	 * 取Count聚合的值
	 * @param term
	 * @return
	 */
	public double getCountAgg(String term) {
		InternalValueCount agg = aggs.get(term);
		if (agg==null) {
			return 0;
		}
		return getDouble(agg.getValue());
	}
	/**
	 * 父term,子count
	 * @param term
	 * @param subTerm
	 * @return
	 */
	public List<JsonObject> getTermSubCountAgg(String term,String subTerm) {
		Terms agg = aggs.get(term);
		if (agg==null) {
			return null;
		}
		List<JsonObject> list = new ArrayList<JsonObject>();
		List<Bucket> buckets = agg.getBuckets();
		for (Bucket bucket : buckets) {
			JsonObject object = new JsonObject();
			object.addProperty("Name", bucket.getKeyAsString());
			object.addProperty("Count", bucket.getDocCount());
			InternalValueCount subAgg = bucket.getAggregations().get(subTerm);
			object.addProperty(subTerm, getDouble(subAgg.getValue()));
			list.add(object);
			
		}
		return list;
	}

	/**
	 * 取min聚合的值
	 * @param term
	 * @return
	 */
	public double getMinAgg(String term) {
		InternalMin agg = aggs.get(term);
		if (agg==null) {
			return 0;
		}
		return getDouble(agg.getValue());
	}
	/**
	 * Term聚合加min
	 * @param term
	 * @param subTerm
	 * @return
	 */
	public List<JsonObject> getTermSubMinAgg(String term,String subTerm){
		Terms agg = aggs.get(term);
		if (agg==null) {
			return null;
		}
		List<Bucket> buckets = agg.getBuckets();
		List<JsonObject> list = new ArrayList<JsonObject>();
		for (Bucket bucket : buckets) {
			JsonObject object = new JsonObject();
			object.addProperty("Name", bucket.getKeyAsString());
			object.addProperty("Count", bucket.getDocCount());
			InternalMin min = bucket.getAggregations().get(subTerm);
			object.addProperty(subTerm, getDouble(min.getValue()));
			list.add(object);
		}
		return list;
	}
	/**
	 * 取max聚合的值
	 * @param term
	 * @return
	 */
	public double getMaxAgg(String term) {
		InternalMax agg = aggs.get(term);
		if (agg==null) {
			return 0;
		}
		return getDouble(agg.getValue());
	}
	/**
	 * Term聚合加max
	 * @param term
	 * @param subTerm
	 * @return
	 */
	public List<JsonObject> getTermSubMaxAgg(String term,String subTerm){
		Terms agg = aggs.get(term);
		if (agg==null) {
			return null;
		}
		List<Bucket> buckets = agg.getBuckets();
		List<JsonObject> list = new ArrayList<JsonObject>();
		for (Bucket bucket : buckets) {
			JsonObject object = new JsonObject();
			object.addProperty("Name", bucket.getKeyAsString());
			object.addProperty("Count", bucket.getDocCount());
			InternalMax min = bucket.getAggregations().get(subTerm);
			object.addProperty(subTerm, getDouble(min.getValue()));
			list.add(object);
		}
		return list;
	}
	
//	public List<Dimension> getDimensions() {
//		return dimensions;
//	}
//
//	public void setDimensions(List<Dimension> dimensions) {
//		this.dimensions = dimensions;
//	}
	
	public double getDouble(Object object){
		try {
			if ("Infinity".equals(String.valueOf(object))||"NaN".equals(String.valueOf(object))) {
				return 0 ;
			}else {
				return Double.parseDouble(String.valueOf(object));
			}
		} catch (NumberFormatException e) {
			return 0;
		}
	}
}
